package com.atg.atgchat.init.user.wxmp.service.imp;

import cn.hutool.core.util.StrUtil;
import com.atg.atgchat.init.user.dao.UserDao;
import com.atg.atgchat.init.user.model.entity.User;
import com.atg.atgchat.init.user.service.UserService;
import com.atg.atgchat.init.user.wxmp.adapter.TextBuilder;
import com.atg.atgchat.init.user.wxmp.adapter.userAdapter;
import com.atg.atgchat.init.user.wxmp.service.WxMsgService;
import com.atg.atgchat.init.websocket.serivce.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/*
author: atg
time: 2025/1/14 10:35
*/
@Service
@Slf4j
public class wxMsgServiceImp implements WxMsgService {
    // openid和code关系
    private static final ConcurrentMap<String,Integer> WAIT_AUTHORIZATION_MAP = new ConcurrentHashMap<>();

    // 获取code
    private static final String SCAN_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
    // 回调地址
    @Value("${atgchat.wx.callback}")
    private String callback;
    @Resource
    private UserDao userDao;
    @Resource
    private UserService userService;

    @Resource
    private WebSocketService webSocketService;

    @Override
    public WxMpXmlOutMessage scan(WxMpService wxMpService, WxMpXmlMessage wxMpXmlMessage) {
        String openId = wxMpXmlMessage.getFromUser();
        //扫码事件处理
        Integer eventKeyCode =  getEventKey(wxMpXmlMessage);
        if (Objects.isNull(eventKeyCode)) {
            return null;
        }
        // 不为空进行注册
        User user = userDao.getByOpenId(openId);
        boolean registered = Objects.nonNull(user);

        boolean authorized = registered && StrUtil.isNotBlank(user.getAvatar()); // 为授权
        if (registered && authorized) {
            // 登录成功的逻辑，通过code找到channel推送消息
            webSocketService.scanLoginSuccess(eventKeyCode, user.getId());
            return null;
        }
        if (!registered) {
            // 注册逻辑
            User buildUser = userAdapter.buildUser(openId);
//            userDao.save(buildUser);
            userService.register(buildUser);
        }
        //公众后点击授权逻辑
        WAIT_AUTHORIZATION_MAP.put(openId, eventKeyCode);
        // 扫码之后给前端一个提示
        webSocketService.sendMessageWaitAuthorization(eventKeyCode);
        //  扫码--
//        第一步：用户同意授权，获取code
        String appId = wxMpService.getWxMpConfigStorage().getAppId();
        String redirectUri = callback + "/wx/portal/public/callBack";
        String authorizeUrl = String.format(SCAN_URL, appId, URLEncoder.encode(redirectUri));

        return TextBuilder.build("请点击链接授权：<a href=\"" + authorizeUrl + "\">登录</a>", wxMpXmlMessage, wxMpService);

    }

    private Integer getEventKey(WxMpXmlMessage wxMpXmlMessage) {
        try {
            String eventKey = wxMpXmlMessage.getEventKey();
            String code = eventKey.replace("qrscene_", "");
            return Integer.parseInt(code);
        } catch (Exception e) {
            log.error("扫码事件处理失败", e);
            return null;
        }
    }

    @Override
    public void authorize(WxOAuth2UserInfo userInfo) {
        String openid = userInfo.getOpenid();
        User user = userDao.getByOpenId(openid);
        // 更新用户信息
        if (StrUtil.isBlank(user.getAvatar())) {
            updateUserInfo(user.getId(), userInfo);
        }
        // 通过code找到channel推送消息
        Integer removeCode = WAIT_AUTHORIZATION_MAP.remove(openid);
        if (removeCode != null) {
            log.info("Removed code for openid {}: {}", openid, removeCode);
            webSocketService.scanLoginSuccess(removeCode, user.getId());
            // 添加发送消息的逻辑

        } else {
            log.warn("No code found for openid {}", openid);
        }
    }

    private void updateUserInfo(Long id, WxOAuth2UserInfo userInfo) {
        User user = userAdapter.buildAuthorizeUser(id, userInfo);
        // 用户名唯一
        String originalUsername = user.getName();
        String username = originalUsername;
        boolean isUnique = false;
        while (!isUnique) {
            Boolean existsByUsername = userDao.existsByUsername(username);
            if (existsByUsername) {
                username = generateRandomUsername(originalUsername);
            } else {
                isUnique = true;
            }
        }
        user.setName(username);
        userDao.updateById(user);
    }

    // 新增方法：生成随机用户名
    private String generateRandomUsername(String originalUsername) {
        Random random = new Random();
        int randomNumber = random.nextInt(10000); // 生成0到9999之间的随机数
        return originalUsername + "_" + randomNumber;
    }


}
